export type ShapeType = 'Rectangle' | 'Circle' | 'Path' | 'Cube';

export interface StateProvider {
  getScale(): number;
  // 未来可以扩展其他状态获取方法
  // getStrokeColor(): string;
  // getStrokeWidth(): number;
  // getMode(): DrawingMode;
}

export interface Point {
  x: number;
  y: number;
}

export interface ShapeProperties {
  type: ShapeType;
  color: string;
  lineWidth: number;
  position: { x: string; y: string };
  startPoint?: { x: number; y: number };
  endPoint?: { x: number; y: number };
  pointCount?: number;
  pathLength?: string;
  points?: Point[];
  endPosition?: { x: string; y: string };
  dimensions?: { width: string; height: string; depth?: string };
  center?: { x: string; y: string };
  radius?: string;
  diameter?: string;
  circumference?: string;
  area?: string;
  volume?: string;
  [key: string]: unknown;
}

export interface Bounds {
  left: number;
  right: number;
  top: number;
  bottom: number;
}

export interface AnchorPoint {
  x: number;
  y: number;
  type: string;
}

// 形状基类
export abstract class Shape {
  public x: number;
  public y: number;
  public color: string;
  public lineWidth: number;
  public selected: boolean;
  public anchors: AnchorPoint[] = [];
  protected stateProvider: StateProvider;

  constructor(
    x: number,
    y: number,
    color: string = 'blue',
    lineWidth: number = 2,
    stateProvider: StateProvider,
  ) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.lineWidth = lineWidth;
    this.selected = false;
    this.stateProvider = stateProvider;
  }

  abstract draw(ctx: CanvasRenderingContext2D): void;
  abstract updateEnd(x: number, y: number): void;
  abstract contains(x: number, y: number): boolean;
  abstract getProperties(): ShapeProperties;
  abstract getBounds(): Bounds | null;
  updateProperty(prop: string, value: string): void {
    // 统一处理颜色和线宽属性
    if (prop === 'color') {
      this.color = value;
    } else if (prop === 'lineWidth') {
      this.lineWidth = Number.parseFloat(value);
    }
  }

  abstract updateSpecificProperty(prop: string, value: string): void;
  abstract createAnchors(): void;

  drawSelection(ctx: CanvasRenderingContext2D): void {
    const bounds = this.getBounds();
    if (!bounds) return;

    const scale = this.stateProvider.getScale();

    ctx.save();
    
    // 绘制选择框
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 2 / scale;
    ctx.setLineDash([5 / scale, 5 / scale]);
    ctx.beginPath();
    ctx.rect(
      bounds.left,
      -bounds.bottom,
      bounds.right - bounds.left,
      -(bounds.top - bounds.bottom),
    );
    ctx.stroke();

    // 绘制锚点
    if (this.anchors.length > 0) {
      ctx.setLineDash([]);
      ctx.fillStyle = 'white';
      ctx.strokeStyle = 'red';
      ctx.lineWidth = 1 / scale;

      this.anchors.forEach((anchor) => {
        ctx.beginPath();
        ctx.arc(anchor.x, -anchor.y, 4 / scale, 0, Math.PI * 2);
        ctx.fill();
        ctx.stroke();
      });
    }

    ctx.restore();
  }
}
